package jcer.core;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/*
 * header: version,bodyLen,cmd,magicNum
 * 
 * request body:count,<length,taskId,taskNum,data>count
 * response body:count,<length,taskId,taskNum,data>count
 */
public class Packet {
	static Log logger = LogFactory.getLog(Packet.class);

	static int VERSION_LEN = 10;
	/*
	 * head
	 */
	public String version;// 10byte
	public byte[] versionStream = new byte[VERSION_LEN];
	public int bodyLen;
	public int cmd;
	public int magicNum;
	public int taskCount;
	public List<TaskPacket> taskPackets;

	/**
	 * unpack the request header
	 * 
	 * @param buf
	 */
	public void unpackHeader(ByteBuffer buf) {
		buf.get(versionStream);
		version = new String(versionStream);
		bodyLen = buf.getInt();
		cmd = buf.getInt();
		magicNum = buf.getInt();
	}

	public void packHeader(ByteBuffer buf) {
		buf.put(versionStream);
		buf.putInt(bodyLen);
		buf.putInt(cmd);
		buf.putInt(magicNum);
	}

	public void unpackBody(ByteBuffer buf) {
		taskPackets = new ArrayList<TaskPacket>();
		taskCount = buf.getInt();
		for (int i = 0; i < taskCount; i++) {
			int len = buf.getInt();
			int taskId = buf.getInt();
			int taskNum = buf.getInt();
			TaskPacket task = new TaskPacket();
			task.taskId = taskId;
			task.taskNum = taskNum;

			task.buf = ByteBuffer.allocate(len - 8);
			byte[] tmp = new byte[len - 8];
			buf.get(tmp);
			task.buf.put(tmp);

			taskPackets.add(task);
		}
	}

	public void packBody(ByteBuffer buf, List<Result> resultList) {
		buf.putInt(resultList.size());
		for (Result result : resultList) {
			buf.putInt(4 + 4 + result.data.length);// taskId+taskNum+data
			buf.putInt(result.taskId);// task id
			buf.putInt(result.taskNum);// task number
			buf.put(result.data);// request id
		}
	}

	public static int getHeaderLen() {
		return 22;
	}

	public static class TaskPacket {
		public int taskId;
		public int taskNum;
		public ByteBuffer buf;
	}

}
